home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
ue312src.zip
/
TIPC.C
< prev
next >
Wrap
Text File
|
1993-03-01
|
21KB
|
544 lines
/*
* TIPC.C - TI Professional and compatible terminal driver for MicroEmacs.
* This version by Ronald Lepine, Moderator - TI Conference
* Byte Information Exchange.
*
* BIX ID. ronlepine
* Programers Room - Ronald Lepine (317) 742-5533 2400 baud
* AT&T: (302) 836-8398
* US Mail:
* Ron Lepine
* 434 Shai Circle
* Bear, DE 19701-3604
*
* Adapted from code by Danial Lawrence for the IBM-PC.
*
* February 1993, David G. Holm (email address: dgh@bix.com)
* Updated to work with new TERM structure in 3.12 BETA 1.
* Updated to work with Borland's C/C++ compilers.
*
* The routines in this file provide support for the TI-PC and other
* compatible terminals. It truely writes directly to the screen RAM to do
* screen output. It compiles into nothing if not a TI-PC driver.
*
* This driver for the TIPC is not the same one that Daniel Lawrence
* distributes. He uses TI's DSRs for most functions as you can see by
* looking at the driver in ue311c.arc. Dan's reverse video
* also does not work. But do not blame him as I'm sure he does not
* have a TIPC to test Emacs on and he *is* supportting the TIPC.
* [Well, as you can see, it is the one I distribute now! - DAN]
* This driver uses direct writes to screen memory except for the message
* line like the IBM driver. In fact I keep TI and IBM versions around by
* having my make file replace estruct.h with one that has a IBMPC defined
* only when I compile IBMPC.C and then switching back to estruct.h with
* TIPC defined. Its last step is of course linking in the correct object
* module for each exe.
*
* You can define any buffer to be reverse video by setting the
* foreground to "BLACK" and the background to any other color
* such as "cyan" to get Black on Cyan text. There is no way to get
* colors such as 'White on blue' on the TIPC unless it has a
* least a 1-plane graphics card in it. If it does have a graphics
* card installed the code to change overall background
* color is tied to the $palette variable with the same values as
* TI BASIC and the Tech Reference manual section 3.5.2 as well as
* being the #define for the color here without the enable attribute.
* The text mode forground/background code still works even when you
* use a $palette backgound giving you a wide range of what can be
* done even though some combinations don't really work too well.
*
* The only reason that there are any '#if color' directives is because of
* the need to maintain structure alignments. This is because TI's mono
* is really 8 shades instead of 8 colors and all attributes remain the
* same. You can have color and mono attached at the same time and
* display on both without any program support or hardware changes. So
* you should define color. It *will* make a difference in other areas of
* the MicroEmacs code. You also do not have to do anything special for
* the palette code because writing to a nonexistant graphics plane on a
* TI causes *no* ill effects (at least according to the tech manual).
*
* Note that if you recieve MicroEmacs for the TIPC compiled by me
* it is compiled/linked so that wildcard file names on the command
* line are automagicly expanded in case you want to work with several
* similarly named files.
*
* Changes to the other files to support the the TIPC MEMAPed
* version compiled under Zortech C/C++ 1.02 to 2.10 follow.
* BTW - The version I used is 2.18 but the earlier versions should
* still be similar since I have compiled previous versions under whatever
* was current at the time and even the previous ZTC version sometimes.
*
* [I simply added Ron's #ifdef changes to the master sources - Dan]
*
* I once thought there were three ways to correct the problems with
* DSR writes to the *25th* line, I now know some don't work.
* One was to check the start register before all screen writes. After
* some investigation and testing I found that the 6545A Start of screen
* registers are write only. So there is not way to correct cursor
* postioning and line position whenever DOS has changed the register.
* Changing the start of screen pointer to offset 0 before screen writes
* also didn't solve the problem completely. As soon as you touched a key
* after the error you ended up with the screen properly postioned, but
* you had the error message on the screen until that line was updated so
* you still ended up using a ^L to correct the screen.
* Two is to capture critical errors (mlwrite and errors are the sources
* of DSR writes to the 25th line) and handle them myself (asm is
* only clean way) and now looks like the only way it is possible but must
* be used in conjuction with a modified method three too.
* Three was change writes to the message line to direct screen writes
* and initialize the screen so that a critical error will write to the
* text portion of the screen where any repaints would clear it. The same
* problems cropped up that did in number one where you needed to do a ^L
* to totally clean up the screen if the error occured while on the message
* line anyway so....
* Therefore a combination of two and three is most likely the best
* way if it can be done since TI does not recommend mixing DSR and direct
* writes to screen (if I could read the 6545 registers 0Bh and 0Ch I
* could manage it though). This is because the DSR writes *can* change
* the screen start register. The problem with a 2+3 solution is mainly
* that the extra code to handle single character writes, directly
* controlling the cursor though the CRTC cursor registers, and the
* intercept/write/read error code handling bloats the code a bit and
* coding in anything but assembly language (which then needs to be
* interfaced to each C compiler that might be in use) is the only reasonable
* way. I just came came to the conclusion that it wasn't worth it since
* a ^L will clear things up anyway after the error is corrected.
*
* 12/29/89 -
* Changed lnptr, sline, and scptr to char/char*'s because TI writes
* only a character at a screen position and IBM a char + attribute. TI's
* attributes are kept up by the hardware except when changed. So we only
* write a char at a time, not an int like the IBM code did. This also
* corrected a minor bug with the message line eeol's which is why I
* looked at the driver code again.
*
* 12/30/89 -
* added the capability of setting the background on machines with
* graphics by setting the palette string with a number from 0 to 7.
* you do this with ^XA $palette (note small letters) and a value.
* Values >= 8 will work since I do modulo division on the value
* but results are the same as the color values in TI BASIC. The
* code, as always, works on all TI's but will not produce a change
* on non-graphics equiped TI's. This code also does not need a color
* monitor to work since a TI doesn't know what kind of monitor is
* attached and may even have color and mono attached at once.
*
* With the code set up so you can still do reverse video on any TI
* by defining BLACK and yellow (or any other background color) you
* have a large variety of posible screen setups. So experiment.
*
* 12/31/89 to 1/7/90 - experimented with various methods of eliminating
* problems with mixed DSR/Direct_Memory writes. Decided not to really
* attempt a solution at this time. Write Ron Lepine if you have
* any feelings/suggestions on this problem, they are welcome.
*
* 1-9-90
* 3.10.c(Beta) New IBMPC reverse video code added to TIPC driver.
*
* Addional changes to 3.10.c(beta) to get it to compile with Zortech C/C++
* **** NOTE THESE CHANGES ARE NO LONGER NEEDED FOR ZTC 2.10 *****
* isearch line 172/5, 191 - change lines to
*
* if (kfunc == &forwsearch || kfunc == &forwhunt ||
* kfunc == &backsearch || kfunc == &backhunt)
* {
* dir = (kfunc == &backsearch || kfunc == &backhunt)?
* REVERSE: FORWARD;
*
* 5-26-90
* Updated first part of this file to reflect 3.11beta line numbers
* while compiling 3.11 beta under Zortech C/C++ 2.1.
*
* 6-04-91
* Added last eight needed values to ctrans[] so standard emacs.rc file
* now works.
*/
#define termdef 1 /* don't define "term" external */
#include <stdio.h>
#include "estruct.h"
#include "eproto.h"
#include "edef.h"
#include "elang.h"
#if TIPC
#define NROW 25 /* Screen height. */
#define NCOL 80 /* Screen width */
#define MARGIN 8 /* size of minimim margin and */
#define SCRSIZ 64 /* scroll size for extended lines */
#define NPAUSE 200 /* # times thru update to pause */
#define BEL 0x07 /* BEL character. */
#define ESC 0x1B /* ESC character. */
#define SPACE 32 /* space character */
#define SCADD 0xDE000000L /* address of screen RAM */
#define ATTRADD 0xDE001800L /* Address for attribute latch */
#define BLUE_PLANE 0xC0000000L /* Address Blue graphics plane */
#define RED_PLANE 0xC8000000L /* Address Red graphics plane */
#define GREEN_PLANE 0xD0000000L /* Address Green graphics plane */
#define CRTC_REG 0xDF810000L /* 6545 CRT Controller access addr */
#define CHAR_ENABLE 0x08 /* TI attribute to show char */
#define TI_REVERSE 0x10 /* TI attribute to reverse char */
#define BLACK 0+CHAR_ENABLE /* TI attribute for Black */
#define BLUE 1+CHAR_ENABLE /* TI attribute for Blue */
#define RED 2+CHAR_ENABLE /* TI attribute for Red */
#define MAGENTA 3+CHAR_ENABLE /* TI attribute for Magenta */
#define GREEN 4+CHAR_ENABLE /* TI attribute for Green */
#define CYAN 5+CHAR_ENABLE /* TI attribute for Cyan */
#define YELLOW 6+CHAR_ENABLE /* TI attribute for Yellow */
#define WHITE 7+CHAR_ENABLE /* TI attribute for White */
PASCAL NEAR ttopen(); /* Forward references. */
PASCAL NEAR ttgetc();
PASCAL NEAR ttputc();
PASCAL NEAR ttflush();
PASCAL NEAR ttclose();
PASCAL NEAR timove();
PASCAL NEAR tieeol();
PASCAL NEAR tieeop();
PASCAL NEAR tibeep();
PASCAL NEAR tiopen();
PASCAL NEAR tikopen();
PASCAL NEAR tirev();
PASCAL NEAR ticres();
PASCAL NEAR ticlose();
PASCAL NEAR tikclose();
PASCAL NEAR tiputc();
PASCAL NEAR tifcol();
PASCAL NEAR tibcol();
PASCAL NEAR scinit();
int revflag = FALSE; /* are we currently in rev video? */
int cfcolor = -1; /* current forground color */
int cbcolor = -1; /* current background color */
int ctrans[] = /* ANSI to TI color translation table */
{BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE,
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE};
char *scptr[NROW]; /* pointer to screen lines-8 bit on ti *
char sline[NCOL]; /* screen line image */
#if __TURBOC__
char far * scadd = SCADD; /* address of screen ram */
char far * attradd = ATTRADD; /* address of attribute latch */
char far * blue_plane = BLUE_PLANE; /* address of blue graphics plane */
char far * red_plane = RED_PLANE; /* address of red graphics plane */
char far * green_plane = GREEN_PLANE; /* address of green graphics plane */
char far * crtc_reg = CRTC_REG; /* 6545 CRT controller address */
#else
long scadd = SCADD; /* address of screen ram */
long attradd = ATTRADD; /* address of attribute latch */
long blue_plane = BLUE_PLANE; /* address of blue graphics plane */
long red_plane = RED_PLANE; /* address of red graphics plane */
long green_plane = GREEN_PLANE; /* address of green graphics plane */
long crtc_reg = CRTC_REG; /* 6545 CRT controller address */
#endif
/*
* Standard terminal interface dispatch table. Most of the fields point into
* "termio" code.
*/
TERM term = {
NROW-1,
NROW-1,
NCOL,
NCOL,
0,
0,
MARGIN,
SCRSIZ,
NPAUSE,
tiopen,
ticlose,
tikopen,
tikclose,
ttgetc,
tiputc,
ttflush,
timove,
tieeol,
tieeop,
tieeop,
tibeep,
tirev,
ticres
#if COLOR
, tifcol,
tibcol
#endif
};
extern union REGS rg;
PASCAL NEAR tifcol(color) /* set the current output color */
int color; /* color to set */
{
cfcolor = ctrans[color];
}
PASCAL NEAR tibcol(color) /* set the current background color */
/* color to set */
int color;
{
cbcolor = ctrans[color];
}
PASCAL NEAR timove(row, col)
int row;
int col;
{
rg.h.ah = 2; /* set cursor position function code */
rg.h.dh = col;
rg.h.dl = row;
int86(0x49, &rg, &rg);
}
PASCAL NEAR tieeol() /* erase to the end of the line */
{
int i; /* loop variable */
char *lnptr; /* pointer to the destination line */
int ccol; /* current column cursor lives */
int crow; /* current row cursor lives */
/* find the current cursor position */
rg.h.ah = 3; /* read cursor position function code */
int86(0x49, &rg, &rg);
ccol = rg.h.dh; /* record current column */
crow = rg.h.dl; /* and row */
lnptr = &sline[0]; /* set things up */
for (i=0; i < term.t_ncol; i++)
*lnptr++ = SPACE;
_fmemset(attradd, cfcolor, 1); /* write current attrs to latc
movmem(&sline[0], scptr[crow]+ccol, term.t_ncol-ccol);
}
PASCAL NEAR tiputc(ch) /* put a character at the current position */
/* in the current colors */
int ch;
{
_fmemset(attradd, cfcolor, 1); /* write current attrs to latch */
rg.h.ah = 0x0E; /* write char to screen with DSR */
rg.h.al = ch;
int86(0x49, &rg, &rg);
}
PASCAL NEAR tieeop() /* Actually a clear screen */
{
rg.h.ah = 0x13; /* Clear Text Screen, Home Cursor and */
int86(0x49, &rg, &rg); /* Set screen start register to 0 */
}
PASCAL NEAR tirev(state) /* change reverse video state */
int state; /* TRUE = reverse, FALSE = normal */
{
revflag = state;
}
PASCAL NEAR ticres() /* Change screen resolution. Should we add the */
/* the 720x350 mode besides the normal 720x300 */
/* mode for those who can handle it? It really */
/* gains us nothing since we don't gain lines */
/* and the code works when started in that res. */
/* Let me (Ron Lepine) know what you think */
{
return(TRUE);
}
PASCAL NEAR tibeep()
{
bdos(6, BEL, 0);
}
PASCAL NEAR tiopen()
{
strcpy(sres, "NORMAL");
revexist = TRUE;
revflag = FALSE;
scinit();
ttopen();
}
PASCAL NEAR tikopen()
{
/* Does nothing */
}
PASCAL NEAR ticlose()
{
_fmemset(attradd, WHITE, 1); /* write normal attrbute to latch */
/* Makes sure we return with a normal color */
/* and not reverse video or such. Attribute */
/* Latch will otherwise hold last color and */
/* attributes it wrote to the screen, which in */
/* some cases is reverse video. */
}
PASCAL NEAR tikclose()
{
_fmemset(attradd, WHITE, 1); /* write normal attrbute to latch */
/* Dan doesn't close the the terminal when shelling */
/* This ensures the shell starts with a normal color */
/* the same way ticlose does without changing */
/* *any* other source file. The only real reason we */
/* place it here is to change as few files as posible */
}
PASCAL NEAR scinit() /* initialize the screen head pointers to */
/* logical screen */
{
union {
long laddr; /* long form of address */
char *paddr; /* pointer form of address */
} addr;
char i;
tieeop(); /* set logical = physical start of screen */
/* initialize The screen pointer array */
for (i = 0; i < NROW; i++) {
addr.laddr = scadd + (long)(NCOL * i);
scptr[i] = addr.paddr;
}
}
PASCAL NEAR scwrite(int row, char *outstr, int forg, int bacg, int revleft, int
/* write a line out */
{
char *lnptr; /* Pointer to the destination line */
char i;
/* Write the attribute byte to latch and setup the screen pointer */
/* If forg == 0 then you can change the back ground to color. TI */
/* won't let you use two colors for forground and background unless */
/* you have graphics and set the graphics color to your background */
/* This is enabled in this driver though the $palette variable */
if ((forg != 0) & (!revflag)) {
forg = ctrans[forg];
_fmemset(attradd, forg, 1);
}else if ((forg != 0) & (revflag)) {
forg = ctrans[forg] + TI_REVERSE;
_fmemset(attradd, forg, 1);
}else{
bacg = ctrans[bacg] + TI_REVERSE;
_fmemset(attradd, bacg, 1);
}
lnptr = &sline[0];
for (i=0; i<term.t_ncol; i++)
*lnptr++ = outstr[i];
/* and send the string out */
movmem(&sline[0], scptr[row], term.t_ncol);
}
PASCAL NEAR spal(palette) /* change palette string */
char *palette;
{
/* Turns on a graphics plane if it is installed */
/* Set value of $palette works the same as in TI BASIC */
/* and the Technical Reference manual section 3.5.2 */
/* ie. Set $palette to 7 for a white background or to */
/* 1 for a blue background. */
/* Causes no problems when graphics are not installed */
/* so there is no reason to check for the number of */
/* graphics planes installed. */
switch ((atoi(palette) % 8)) {
case 0:
_fmemset(blue_plane, 0, 0x7fff);
_fmemset(red_plane, 0, 0x7fff);
_fmemset(green_plane, 0, 0x7fff);
break;
case 1:
_fmemset(blue_plane, 0xff, 0x7fff);
_fmemset(red_plane, 0, 0x7fff);
_fmemset(green_plane, 0, 0x7fff);
break;
case 2:
_fmemset(blue_plane, 0, 0x7fff);
_fmemset(red_plane, 0xff, 0x7fff);
_fmemset(green_plane, 0, 0x7fff);
break;
case 3:
_fmemset(blue_plane, 0xff, 0x7fff);
_fmemset(red_plane, 0xff, 0x7fff);
_fmemset(green_plane, 0, 0x7fff);
break;
case 4:
_fmemset(blue_plane, 0, 0x7fff);
_fmemset(red_plane, 0, 0x7fff);
_fmemset(green_plane, 0xff, 0x7fff);
break;
case 5:
_fmemset(blue_plane, 0xff, 0x7fff);
_fmemset(red_plane, 0, 0x7fff);
_fmemset(green_plane, 0xff, 0x7fff);
break;
case 6:
_fmemset(blue_plane, 0, 0x7fff);
_fmemset(red_plane, 0xff, 0x7fff);
_fmemset(green_plane, 0xff, 0x7fff);
break;
case 7:
_fmemset(blue_plane, 0xff, 0x7fff);
_fmemset(red_plane, 0xff, 0x7fff);
_fmemset(green_plane, 0xff, 0x7fff);
break;
}
}
#if FLABEL
PASCAL NEAR fnclabel(f, n) /* label a function key */
int f,n; /* default flag, numeric argument [unused] */
{
/* on machines with no function keys...don't bother */
/* TI/IBM function keys are handled in other code */
return(TRUE);
}
#endif
#else
tihello()
{
}
#endif